package com.rehabilitation.assessment;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.atomic.AtomicBoolean;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.widget.TextView;

import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.Viewport;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;

public class MainActivity extends AppCompatActivity {

    //introduce variables
    private final static String TAG = ">==< ArduinoYun >==<";
    private final static String ARDUINO_IP_ADDRESS = "192.168.240.1";
    private final static int PORT = 6666;

    private TextView mSensorReading;

    private LineGraphSeries<DataPoint> series;
    private int lastX = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //link sensor reading with the UI object
        mSensorReading = (TextView) findViewById(R.id.sensorreading_text_view);

        //link graph with the UI object
        GraphView graph = (GraphView) findViewById(R.id.graph);

        //initialize graph
        series = new LineGraphSeries<>();
        graph.addSeries(series);
        Viewport viewport = graph.getViewport();
        viewport.setYAxisBoundsManual(true);
        viewport.setMinY(0);
        viewport.setMaxY(300);
        viewport.setScrollable(true);

        Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
        setSupportActionBar(myToolbar);

    }

    @Override
    protected void onStart() {
        mStop.set(false);
        if(sNetworkThread == null){
            sNetworkThread = new Thread(mNetworkRunnable);
            sNetworkThread.start();
        }
        super.onStart();
    }

    @Override
    protected void onStop() {
        mStop.set(true);
        if(sNetworkThread != null) sNetworkThread.interrupt();
        super.onStop();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    private AtomicBoolean mStop = new AtomicBoolean(false);

    private BufferedReader in = null;

    private Socket mSocket = null;

    private static Thread sNetworkThread = null;
    private final Runnable mNetworkRunnable = new Runnable() {

        @Override
        public void run() {
            log("starting network thread");


            try {
                mSocket = new Socket(ARDUINO_IP_ADDRESS, PORT);
                in = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
            } catch (UnknownHostException e1) {
                e1.printStackTrace();
                mStop.set(true);
                log("UnknownHostException");
            } catch (IOException e1) {
                e1.printStackTrace();
                mStop.set(true);
            }

            try {
                while (!mStop.get()) {
                    log("receiving value ");
                    final String dataRead = in.readLine();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            mSensorReading.setText(R.string.sensor_reading + dataRead);
                            series.appendData(new DataPoint(lastX++, Integer.parseInt(dataRead)), true, 10);
                        }
                    });
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            finally{
                try {
                    mStop.set(true);
                    if(in != null) in.close();
                    if(mSocket != null) mSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            log("returning from network thread");
            sNetworkThread = null;
        }
    };

    public void log(String s){
        Log.d(TAG, s);
    }

}